package tf2pickup.listeners;

import java.util.HashMap;

import org.pircbotx.PircBotX;
import org.pircbotx.User;
import org.pircbotx.hooks.ListenerAdapter;
import org.pircbotx.hooks.events.KickEvent;
import org.pircbotx.hooks.events.MessageEvent;
import org.pircbotx.hooks.events.PartEvent;

import org.pircbotx.hooks.events.QuitEvent;
import tf2pickup.Config;
import tf2pickup.Players;

/**
 * Takes care of the various reasons, why a player should be removed from
 * the pickup.
 * Will remove players automatically when:
 * - an added player leaves the channel (kick or part or quit)
 * - he wants to remove himself (by the commands !remove / !delete)
 * @author Philipp Preß
 */
public class RemovePlayer extends ListenerAdapter<PircBotX> {

    private Players players;
    private HashMap<String, Integer> maps;
    private Config cfg;

    public RemovePlayer(Players players, HashMap<String, Integer> maps, Config cfg) {
        this.players = players;
        this.maps = maps;
        this.cfg = cfg;
    }

    @Override
    public void onMessage(MessageEvent<PircBotX> event) throws Exception {
        if (event.getMessage().toLowerCase().startsWith("!rem")
                || event.getMessage().toLowerCase().startsWith("!del")) {
            if (!players.containsPlayer(event.getUser().getNick())) {
                event.respond("Cannot remove you from pickup: You are not "
                        + "added to the pickup yet.");
                return;
            }
            this.removePreviousMapVote(event.getUser());
            players.removePlayer(event.getUser().getNick());
            event.respond("You've been successfully removed from the pickup.");
            //Refresh topic
            event.getBot().getListenerManager().dispatchEvent(
                    new MessageEvent<PircBotX>(event.getBot(),
                            event.getChannel(), event.getUser(), "!status"));
        }
    }

    @Override
    public void onKick(KickEvent<PircBotX> event) {
        if (!players.containsPlayer(event.getRecipient().getNick())) {
            return;
        }
        this.removePreviousMapVote(event.getRecipient());
        players.removePlayer(event.getRecipient().getNick());
        event.getBot().sendMessage(event.getChannel(),event.getRecipient() + ": You've been kicked from the pickup as well.");
        //Refresh topic
        event.getBot().getListenerManager().dispatchEvent(
                new MessageEvent<PircBotX>(event.getBot(),
                        event.getChannel(), event.getRecipient(), "!status"));
    }

    @Override
    public void onPart(PartEvent<PircBotX> event) {
        if (!players.containsPlayer(event.getUser().getNick())) {
            return;
        }
        this.removePreviousMapVote(event.getUser());
        players.removePlayer(event.getUser().getNick());
        event.getBot().sendMessage(cfg.ircChannel,
                event.getUser().getNick() + " has been removed from the pickup.");
        //Refresh topic
        event.getBot().getListenerManager().dispatchEvent(
                new MessageEvent<PircBotX>(event.getBot(),
                        event.getChannel(), event.getUser(), "!status"));
    }

    @Override
    public void onQuit(QuitEvent<PircBotX> event) {
        if (!players.containsPlayer(event.getUser().getNick())) {
            return;
        }
        this.removePreviousMapVote(event.getUser());
        players.removePlayer(event.getUser().getNick());
        event.getBot().sendMessage(cfg.ircChannel,
                event.getUser().getNick() + " has been removed from the pickup.");
        //Refresh Topic
        event.getBot().getListenerManager().dispatchEvent(
                new MessageEvent<PircBotX>(event.getBot(),
                event.getBot().getChannel(cfg.ircChannel),
                event.getUser(), "!status"));
    }

    /**
     * If the player has voted for a map, it's vote gets removed.
     * @param user IRC-User of the player whose map-vote should be removed.
     */
    private void removePreviousMapVote(User user) {
        String prevMapVote = players.getPlayerProperties(user.getNick()).getMapVote();
        if (!prevMapVote.isEmpty()) {
            maps.put(prevMapVote, maps.get(prevMapVote) - 1);
            players.getPlayerProperties(user.getNick()).setMapVote("");
        }
    }
}
